/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package autodiarydataprocess;

import java.io.FileInputStream;
import java.io.PrintWriter;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

/**
 *
 * @author thang
 * Prepare training data for ANN
 */
public class TrainingData {
    
         /*
     * fromFile:            sensor data file
     * toFile: each row is: for each window of five samples, convert max, min to range [0,1] by dividing for 20 (bound value)
     * window file:         not used
     * strOutput:           desire out put of neural network 2 bits for 4 activities
     * write:               min, max, max-min, ANN output to training data file
     */
    public void minMinus01Range(String fromFile, String toFile, String windowFile, String strOutput)
    {
        // read from original data file
        // convert to training data file
        Scanner is = null;
        PrintWriter os = null;
        PrintWriter osWindow = null;
        
        try{
            is = new Scanner(new FileInputStream(fromFile));
            os = new PrintWriter(new FileOutputStream(toFile));
            osWindow = new PrintWriter(new FileOutputStream(windowFile));
        }
        catch(FileNotFoundException e){
            System.out.println("Load file error");
            System.exit(0);
        }
        
        // create window 5 samples, slide is zero.

        int windowSize = 5;
        float next = 0;
        String str = "";        // one line to write to trainning data file
        String strWindow = "";  // one line to write to window file
        float[] mWindow = new float[windowSize];
        float[] mMinMax = null;
        
        
        int count = 0;
        while (is.hasNextFloat()){
            //count++;
            mWindow[count] = is.nextFloat();
            strWindow += mWindow[count] + "\t";
            
            if (count == (windowSize - 1)){
                // calculate min max
                mMinMax = minMaxAverage(mWindow);
                // set to bound value of 20:
                if(mMinMax[0] > 20){mMinMax[0] = 20;}
                if(mMinMax[1] > 20){mMinMax[1] = 20;}
                
                // convert max, min in range [0,1] by dividing for 20
                mMinMax[0] = mMinMax[0]/20;                
                mMinMax[1] = mMinMax[1]/20;

                // add ANN desire output
                //str = mMinMax[0] + "," + mMinMax[1] + "," + strOutput;
                str = mMinMax[0] + "," + (mMinMax[1] - mMinMax[0]) + "," + strOutput;
                
                os.println(str);
                // store to window file
                osWindow.println(strWindow);
                // reset window index and window data
                strWindow = "";
                str = "";
                count = 0;
            }else{
                count++;
            }
        }
        is.close();
        os.close();
        osWindow.close();
        System.out.println("Finish convert file: " + fromFile);
    }
    
     /*
     * fromFile:            sensor data file
     * toFile: each row is: for each window of five samples, convert max, min to range [0,1] by dividing for 20 (bound value)
     * window file:         not used
     * strOutput:           desire out put of neural network 2 bits for 4 activities
     * write:               min, max, max-min, ANN output to training data file
     */
    public void minMaxMinus01Range(String fromFile, String toFile, String windowFile, String strOutput)
    {
        // read from original data file
        // convert to training data file
        Scanner is = null;
        PrintWriter os = null;
        PrintWriter osWindow = null;
        
        try{
            is = new Scanner(new FileInputStream(fromFile));
            os = new PrintWriter(new FileOutputStream(toFile));
            osWindow = new PrintWriter(new FileOutputStream(windowFile));
        }
        catch(FileNotFoundException e){
            System.out.println("Load file error");
            System.exit(0);
        }
        
        // create window 5 samples, slide is zero.

        int windowSize = 5;
        float next = 0;
        String str = "";        // one line to write to trainning data file
        String strWindow = "";  // one line to write to window file
        float[] mWindow = new float[windowSize];
        float[] mMinMax = null;
        
        
        int count = 0;
        while (is.hasNextFloat()){
            //count++;
            mWindow[count] = is.nextFloat();
            strWindow += mWindow[count] + "\t";
            
            if (count == (windowSize - 1)){
                // calculate min max
                mMinMax = minMaxAverage(mWindow);
                // set to bound value of 20:
                if(mMinMax[0] > 20){mMinMax[0] = 20;}
                if(mMinMax[1] > 20){mMinMax[1] = 20;}
                
                // convert max, min in range [0,1] by dividing for 20
                mMinMax[0] = mMinMax[0]/20;                
                mMinMax[1] = mMinMax[1]/20;

                // add ANN desire output
                //str = mMinMax[0] + "," + mMinMax[1] + "," + strOutput;
                str = mMinMax[0] + "," + mMinMax[1] + "," + (mMinMax[1] - mMinMax[0]) + "," + strOutput;
                
                os.println(str);
                // store to window file
                osWindow.println(strWindow);
                // reset window index and window data
                strWindow = "";
                str = "";
                count = 0;
            }else{
                count++;
            }
        }
        is.close();
        os.close();
        osWindow.close();
        System.out.println("Finish convert file: " + fromFile);
    }
    
    /*
     * fromFile:            sensor data file
     * toFile: each row is: for each window of five samples, convert max, min to range [0,1] by dividing for 20 (bound value)
     * window file:         not used
     * strOutput:           desire out put of neural network 2 bits for 4 activities
     */
    public void minMax01Range(String fromFile, String toFile, String windowFile, String strOutput)
    {
        // read from original data file
        // convert to training data file
        Scanner is = null;
        PrintWriter os = null;
        PrintWriter osWindow = null;
        
        try{
            is = new Scanner(new FileInputStream(fromFile));
            os = new PrintWriter(new FileOutputStream(toFile));
            osWindow = new PrintWriter(new FileOutputStream(windowFile));
        }
        catch(FileNotFoundException e){
            System.out.println("Load file error");
            System.exit(0);
        }
        
        // create window 5 samples, slide is zero.

        int windowSize = 5;
        float next = 0;
        String str = "";        // one line to write to trainning data file
        String strWindow = "";  // one line to write to window file
        float[] mWindow = new float[windowSize];
        float[] mMinMax = null;
        
        
        int count = 0;
        while (is.hasNextFloat()){
            //count++;
            mWindow[count] = is.nextFloat();
            strWindow += mWindow[count] + "\t";
            
            if (count == (windowSize - 1)){
                // calculate min max
                mMinMax = minMaxAverage(mWindow);
                // set to bound value of 20:
                if(mMinMax[0] > 20){mMinMax[0] = 20;}
                if(mMinMax[1] > 20){mMinMax[1] = 20;}
                
                // convert max, min in range [0,1] by dividing for 20
                mMinMax[0] = mMinMax[0]/20;                
                mMinMax[1] = mMinMax[1]/20;

                // add ANN desire output
                //str = mMinMax[0] + "," + mMinMax[1] + "," + strOutput;
                str = mMinMax[0] + "," + mMinMax[1] + "," + strOutput;
                
                os.println(str);
                // store to window file
                osWindow.println(strWindow);
                // reset window index and window data
                strWindow = "";
                str = "";
                count = 0;
            }else{
                count++;
            }
        }
        is.close();
        os.close();
        osWindow.close();
        System.out.println("Finish convert file: " + fromFile);
    }
    
    /*
     * fromFile:            sensor data file
     * toFile: each row is: for each window of five samples, canculate max - min then convert to binary
     * window file:         not used
     * strOutput:           desire out put of neural network
     */
    public void prepareBinary(String fromFile, String toFile, String windowFile, String strOutput)
    {
        // read from original data file
        // convert to training data file
        Scanner is = null;
        PrintWriter os = null;
        PrintWriter osWindow = null;
        
        try{
            is = new Scanner(new FileInputStream(fromFile));
            os = new PrintWriter(new FileOutputStream(toFile));
            osWindow = new PrintWriter(new FileOutputStream(windowFile));
        }
        catch(FileNotFoundException e){
            System.out.println("Load file error");
            System.exit(0);
        }
        
        // create window 5 samples, silde is zero.

        int windowSize = 5;
        float next = 0;
        String str = "";        // one line to write to trainning data file
        String strWindow = "";  // one line to write to window file
        float[] mWindow = new float[windowSize];
        float[] mMinMax = null;
        
        
        int count = 0;
        while (is.hasNextFloat()){
            //count++;
            mWindow[count] = is.nextFloat();
            strWindow += mWindow[count] + "\t";
            
            if (count == (windowSize - 1)){
                // calculate min max
                mMinMax = minMaxAverage(mWindow);
                // convert (max - min) to binary and add to ANN desire output
                // get max - min in range [0,15]
                int diff = Math.round(mMinMax[1] - mMinMax[0]);
                if (diff < 0) {diff = 0;}
                if (diff > 15){diff = 15;}
                
                String strDiff = Long.toBinaryString(Long.parseLong(String.valueOf(diff)));
                
                // make fix lenght of 4 bit
                for (int i = 0; i < (4 - strDiff.length()); i++){
                    str += "0,";
                }
                // add the binary value
                for (char c: strDiff.toCharArray()){
                    str += c + ",";
                }
                str += strOutput;
                //str = (mMinMax[1] - mMinMax[0]) + "," + mMinMax[2] + "," + strOutput;
                
                os.println(str);
                // store to window file
                osWindow.println(strWindow);
                // reset window index and window data
                strWindow = "";
                str = "";
                count = 0;
            }else{
                count++;
            }
        }
        is.close();
        os.close();
        osWindow.close();
        System.out.println("Finish convert file: " + fromFile);
    }
    
    public void prepareData(String fromFile, String toFile, String windowFile, String strOutput)
    {
        // read from original data file
        // convert to training data file
        Scanner is = null;
        PrintWriter os = null;
        PrintWriter osWindow = null;
        
        try{
            is = new Scanner(new FileInputStream(fromFile));
            os = new PrintWriter(new FileOutputStream(toFile));
            osWindow = new PrintWriter(new FileOutputStream(windowFile));
        }
        catch(FileNotFoundException e){
            System.out.println("Load file error");
            System.exit(0);
        }
        
        // create window 5 samples, silde is zero.

        int windowSize = 5;
        float next = 0;
        String str = "";        // one line to write to trainning data file
        String strWindow = "";  // one line to write to window file
        float[] mWindow = new float[windowSize];
        float[] mMinMax = null;
        
        
        int count = 0;
        while (is.hasNextFloat()){
            //count++;
            mWindow[count] = is.nextFloat();
            strWindow += mWindow[count] + "\t";
            
            if (count == (windowSize - 1)){
                // calculate min max
                mMinMax = minMaxAverage(mWindow);
                // convert to string of (max - min), average
                str = (mMinMax[1] - mMinMax[0]) + "," + mMinMax[2] + "," + strOutput;
                os.println(str);
                // store to window file
                osWindow.println(strWindow);
                // reset window index and window data
                strWindow = "";
                count = 0;
            }else{
                count++;
            }
        }
        is.close();
        os.close();
        osWindow.close();
        System.out.println("Finish convert file: " + fromFile);
    }
    
    // return an array contain min, max, average of input array
    public float[] minMaxAverage(float[] arr){
        float[] result = null;
        if (arr.length < 1){return result;}
        
        //float[] result = [arr[0],arr[0],arr[0]];
        
        float min       = arr[0];
        float max       = arr[0];
        float sum       = arr[0];
        float average   = arr[0];
        
        for (int i = 1; i < arr.length; i++) {
            if (min > arr[i]){ min = arr[i];}
            if (max < arr[i]){ max = arr[i];}
            sum += arr[i];
        }
        
        average = sum/(arr.length);
        
        result = new float[3];
        result[0] = min;
        result[1] = max;
        result[2] = average;
        
        return result;
    }
}
